package VisibilityGraph;

import java.util.ArrayList;
import java.util.Hashtable;
import java.util.LinkedList;

import DataModel.CommonLibrary.CommonDefs;
import DataModel.CommonLibrary.CommonDefs.Layer;
import DataModel.LayoutManager.CLayoutManager;
import DataModel.LayoutManager.CRectangle;
/**
 * Class incapsulates cross capacitence calculation based on rectangles hash
 * @author Guy
 *
 */
public class CrossCap {
	
	/**
	 * Activates calculation of cross capacitence in given layer 
	 * @param manager instance of layout manager
	 * @param l layer to calculate capacitence at
	 * @param cValue capacitance constant
	 * @return total cross capacitence in layer
	 */
	public static double Activate(CLayoutManager manager,Layer l, double cValue) {
		LinkedList<CRectangle> recs = manager.GetRecsInLayer(l);
		return calcCrossCap(recs,'x',cValue)+calcCrossCap(recs,'y',cValue);
	}
	/**
	 * Activates calculation of cross capacitence on input rectangles 
	 * @param recs - input rectangles
	 * @param dir direction for capacitence
	 * @param cValue capacitance constant
	 * @return cross capacitence 
	 */
	public static double calcCrossCap(LinkedList<CRectangle> recs, char dir, double cValue ) {
		double tot_cap =0;
		Hashtable<CommonDefs.Layer,LinkedList<CRectangle>> recsByLayer = new Hashtable<Layer, LinkedList<CRectangle>>();
		for (CRectangle r:recs){
			if (!recsByLayer.containsKey(r.getLayer())) {
				LinkedList<CRectangle> recsInLayer = new LinkedList<CRectangle>();
				recsInLayer.add(r);
				recsByLayer.put(r.getLayer(), recsInLayer);
			} else {
				recsByLayer.get(r.getLayer()).add(r);
			}	
		}
		ArrayList<CommonDefs.Layer> keys = new ArrayList<Layer>(recsByLayer.keySet());

		for (CommonDefs.Layer l :keys) { 
			LinkedList<CRectangle> layerRecs = recsByLayer.get(l);
			NeighboursHash neighboursHash = new NeighboursHash(layerRecs);
			if (dir == 'x') tot_cap+= neighboursHash.getCrossCapAreaX()*cValue;
			if (dir == 'y') tot_cap+= neighboursHash.getCrossCapAreaY()*cValue;
		}
		return tot_cap;
	}

}
